package com.yt.common.utils;

import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;

@Slf4j
public class MarkImageUtils {


    // 水印之间的间隔
    private static final int XMOVE = 200;
    // 水印之间的间隔
    private static final int YMOVE = 200;

    /**
     * 文字水印
     * @param bytes 目标图片路径，如：C://myPictrue//1.jpg
     * @param pressText 水印文字， 如：云账房
     * @param fontName 体名称， 如：宋体
     * @param fontStyle 字体样式，如：粗体和斜体(Font.BOLD|Font.ITALIC)
     * @param fontSize 字体大小，单位为像素
     * @param alpha 透明度(0.0 -- 1.0, 0.0为完全透明，1.0为完全不透明)
     * @param fileExtName 扩展名
     * @param location 水印位置：0、自定义 1、左上角，2、右上角，3、左下角，4、右下角，5、中间,6、默认，7、对角线、8、满铺
     * @param x
     * @param y
     *
     */
    public static byte[] markText(byte[] bytes, String pressText, String fontName, int fontStyle, int fontSize, Color color, float alpha, String fileExtName, Integer location, Integer x, Integer y) {
        try {
            BufferedImage targerImage = doMarkText(ImageUtils.toImage(bytes), fileExtName, pressText, fontName, fontStyle, fontSize, color, alpha, location, x, y);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(targerImage, fileExtName, os);
            return os.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     *
     * 文字水印
     * @param srcUrl 原图片路径，如：C://myPictrue//1.jpg
     * @param targerUrl 目标图片路径，如：C://myPictrue//1.jpg
     * @param pressText 水印文字， 如：云账房
     * @param fontName 体名称， 如：宋体
     * @param fontStyle 字体样式，如：粗体和斜体(Font.BOLD|Font.ITALIC)
     * @param fontSize 字体大小，单位为像素
     * @param alpha 透明度(0.0 -- 1.0, 0.0为完全透明，1.0为完全不透明)
     * @param location      水印位置：0、自定义 1、左上角，2、右上角，3、左下角，4、右下角，5、中间
     * @param x
     * @param y
     *
     */
    public static void markText(String srcUrl, String targerUrl, String pressText, String fontName, int fontStyle, int fontSize, Color color, float alpha, String fileExtName, Integer location, Integer x, Integer y) {

        try {
            File file = new File(srcUrl);
            BufferedImage targerImage = doMarkText(ImageUtils.toImage(file), fileExtName, pressText, fontName, fontStyle, fontSize, color, alpha, location, x, y);
            File targerFile = new File(targerUrl);
            //注意这里的后缀不能带 .
            ImageIO.write(targerImage, fileExtName, targerFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理文字水印
     * @param srcImage
     * @param pressText
     * @param fontName
     * @param fontStyle
     * @param fontSize
     * @param color
     * @param alpha
     * @param location
     * @param x
     * @param y
     * @return
     */
    public static BufferedImage doMarkText(BufferedImage srcImage, String fileExtName, String pressText, String fontName, int fontStyle, int fontSize, Color color, float alpha, Integer location, Integer x, Integer y){

        int srcWidth = srcImage.getWidth();
        int srcHeight = srcImage.getHeight();

        Font font = new Font(fontName, fontStyle, fontSize);

        BufferedImage buffImg = new BufferedImage(srcWidth, srcHeight, BufferedImage.TYPE_INT_RGB);

        /**2、得到画笔对象*/
        Graphics2D g2d = buffImg.createGraphics();

        if("png".equals(fileExtName.toLowerCase())){
            // ----------  增加下面的代码使得背景透明  -----------------
            buffImg = g2d.getDeviceConfiguration().createCompatibleImage(srcWidth, srcHeight, Transparency.TRANSLUCENT);
            g2d.dispose();
            g2d = buffImg.createGraphics();
            // ----------  背景透明代码结束  -----------------
        }

        // 设置对线段的锯齿状边缘处理
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        //把源图片写入
        g2d.drawImage(srcImage.getScaledInstance(srcWidth, srcHeight, Image.SCALE_SMOOTH), 0, 0,null);
        // 设置水印旋转
        //0、自定义 1、左上角，2、右上角，3、左下角，4、右下角，5、中间,6、默认，7、对角线、8、满铺
        if(location != null && (location == 7 || location == 8)){
            g2d.rotate(Math.toRadians(-45),(double) buffImg.getWidth() / 2,(double) buffImg.getHeight() / 2);
        }

        // 设置颜色
        g2d.setColor(color);
        // 设置 Font
        g2d.setFont(font);

        //设置透明度:1.0f为透明度 ，值从0-1.0，依次变得不透明
        if(!(alpha > 0 && alpha < 1)){
            if(alpha > 1 && alpha < 100){
                alpha = alpha /100;
            } else {
                alpha = 1;
            }
        }
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));
//        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));//透明度设置 结束

        //获取文字所占的像素
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D stringBounds = font.getStringBounds(pressText,context);
        int textWidth = (int) stringBounds.getWidth() ;
        int textHeight = (int) stringBounds.getHeight();

        // 根据位置参数确定坐标位置
        // location 位置： 1、左上角，2、右上角，3、左下角，4、右下角，5、中间
        switch (location) {
            case 0:
                g2d.drawString(pressText, x, y);
                break;
            case 1:
                x = textHeight;
                y = textHeight * 2;
                g2d.drawString(pressText, x, y);
                break;
            case 2:
                x = srcWidth - textWidth - textHeight;
                y = textHeight * 2;
                g2d.drawString(pressText, x, y);
                break;
            case 3:
                x = textHeight;
                y = srcHeight - textHeight * 2;
                g2d.drawString(pressText, x, y);
                break;
            case 4:
                x = srcWidth - textWidth - textHeight;
                y = srcHeight - textHeight*2;
                g2d.drawString(pressText, x, y);
                break;
            case 5:
                x = (srcWidth - textWidth) / 2;
                y = (srcHeight - textHeight) / 2;
                g2d.drawString(pressText, x, y);
                break;
            case 6:
                // 竖着水印
                x = srcWidth / 2 - (textWidth / 2);
                y = 0;
                while (y < srcHeight) {
                    y +=  textHeight + YMOVE;
                    g2d.drawString (pressText, x, y);
                }
                break;
            case 7:
                x = (srcWidth - textWidth) / 2;
                y = (srcHeight - textHeight) / 2;
                g2d.drawString(pressText, x, y);
                break;
            case 8:
                srcWidth = srcHeight;

                x = -srcWidth / 2;
                y = 0;

                // 循环添加水印
                while (x < srcWidth) {
                    y = -srcHeight / 2;
                    while (y < srcHeight) {
                        g2d.drawString (pressText, x, y);

                        y += textHeight + 100;
                    }
                    x += textWidth + 100;
                }
                break;
            default: break;
        }

        //释放资源
        g2d .dispose();

        return buffImg;
    }

    /**
     * 获取文本长度。汉字为1:1，英文和数字为2:1
     */
    private static int getTextLength (String text) {
        int length = text.length ();
        for (int i = 0; i < text.length (); i++) {
            String s = String.valueOf (text.charAt (i));
            if (s.getBytes ().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }


    /**
     * 处理图片水印
     * @param srcUrl 原图片
     * @param waterUrl 水印图片
     * @param targerUrl 目标图片
     * @param fileExtName 扩展名
     * @param location 水印位置：0、自定义 1、左上角，2、右上角，3、左下角，4、右下角，5、中间
     * @param degree 旋转角：顺时针角度
     * @param x
     * @param y
     */
    public static void markImage(String srcUrl, String waterUrl, String targerUrl, String fileExtName, Integer location, Integer degree, Integer x, Integer y){

        try{
            BufferedImage targerImage = doMarkImage(ImageUtils.toImage(srcUrl), ImageUtils.toImage(waterUrl), location, degree, x, y);
            ImageIO.write(targerImage, fileExtName, new File(targerUrl));
        } catch (Exception e){
            e.printStackTrace();
            log.error("doMarkImage is error", e);
        }

    }

    /**
     * 处理图片水印
     * @param srcBytes 原图片
     * @param waterBytes 水印图片
     * @param fileExtName 扩展名
     * @param location 水印位置：0、自定义 1、左上角，2、右上角，3、左下角，4、右下角，5、中间
     * @param degree 旋转角：顺时针角度
     * @param x
     * @param y
     */
    public static byte[] markImage(byte[] srcBytes, byte[] waterBytes, String fileExtName, Integer location, Integer degree, Integer x, Integer y){
        try {
            BufferedImage targerImage = doMarkImage(ImageUtils.toImage(srcBytes), ImageUtils.toImage(waterBytes), location, degree, x, y);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(targerImage, fileExtName, os);
            return os.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 处理图片水印
     * @param srcImage 原图片
     * @param waterImage 水印图片
     * @param location 水印位置：0、自定义 1、左上角，2、右上角，3、左下角，4、右下角，5、中间
     * @param degree 旋转角：顺时针角度
     */
    public static BufferedImage doMarkImage(BufferedImage srcImage, BufferedImage waterImage, Integer location, Integer degree, Integer x, Integer y) {
        try {
            int width = srcImage.getWidth();
            int height = srcImage.getHeight();

            BufferedImage targerImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            // 得到画笔对象
            Graphics2D g = targerImage.createGraphics();

            // 设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImage, 0, 0, width, height, null);
            if (null != degree) {
                // 设置水印旋转
                //TODO:
                degree = -45;
                g.rotate(Math.toRadians(degree), (double) targerImage.getWidth() / 2, (double) targerImage.getHeight() / 2);
            }
            float alpha = 0.5f; // 透明度
            int syWidth = waterImage.getWidth();
            int syHeight = waterImage.getHeight();

            // 如果水印图片高或宽大于目标图片是做的处理，使水印宽或高等于目标图片的宽高，并且等比例缩放
            int newSyWidth = syWidth;
            int newSyHeight = syHeight;

            if (syWidth > width) {
                newSyWidth = width;
                newSyHeight = (int) ((double)newSyWidth / syWidth * height);
            }

            if (newSyHeight > height) {
                newSyHeight = height;
                newSyWidth = (int) ((double)newSyHeight / syHeight * newSyWidth);
            }

            // 根据位置参数确定坐标位置
            // location 位置： 1、左上角，2、右上角，3、左下角，4、右下角，5、中间
            switch (location) {
                case 0: break;
                case 1:
                    x = 0;
                    y = 0;
                    break;
                case 2:
                    x = width - newSyWidth;
                    break;
                case 3:
                    y = height - newSyHeight;
                    break;
                case 4:
                    x = width - newSyWidth;
                    y = height - newSyHeight;
                    break;
                case 5:
                    x = (width - newSyWidth) / 2;
                    y = (height - newSyHeight) / 2;
                    break;
                default: break;
            }

            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 表示水印图片的位置
            g.drawImage(waterImage, x, y, newSyWidth, newSyHeight, null);
            // 水印文件结束
            g.dispose();
            return targerImage;
        } catch (Exception e) {
            log.info("图片添加Icon印章异常！ ", e);
        }
        return null;
    }

    /**
     * 将字节流写到指定文件
     * @param os
     * @param file
     */
    public static void writeFile(ByteArrayOutputStream os, File file){
        FileOutputStream fos = null;
        try {
            byte[] bytes = os.toByteArray();
            if (file.exists()) {
                file.delete();
            }
            fos = new FileOutputStream(file);
            fos.write(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 创建图片缩略图(等比缩放)
     *
     * @param image 目标图片文件完整路径
     * @param width 缩放的宽度
     * @param height 缩放的高度
     */
    public static BufferedImage createThumbnail(BufferedImage image, int width, int height) {
        try {
            BufferedImage buffImg = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);

            /**2、得到画笔对象*/
            Graphics2D g2d = buffImg.createGraphics();

            // ----------  增加下面的代码使得背景透明  -----------------
            buffImg = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
            g2d.dispose();
            g2d = buffImg.createGraphics();
            // ----------  背景透明代码结束  -----------------
            g2d.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);

            return buffImg;
        } catch (Exception e) {
            System.out.println("创建缩略图发生异常" + e.getMessage());
        }
        return null;
    }

    public static void main(String[] args) {
        String srcUrl = "/Users/mxli/Desktop/首页-已登陆.png";
        String targerUrl = "/Users/mxli/Desktop/targer_mark.png";
        File targerFile = new File(targerUrl);

        File file = new File(srcUrl);
        Integer x = null;
        Integer y = null;
        try {
            InputStream input = new FileInputStream(file);
//            Color color = Color.decode("#EE6363");
//            Color color = Color.decode("#F60340");
            Color color = Color.decode("#C2B7B6");
//            byte[] bytes = pressText(FileUtils.inputStream2byte(input), "中铁工服", "宋体", Font.BOLD, 22, color, 0.5f, 90, fileExtName);
//            ImageIO.write(ImageUtils.toImage(bytes), fileExtName, targerFile);
//            markImage(srcUrl, waterUrl, targerUrl, -1, -1, 0, null, fileExtName);
//            markText(srcUrl, targerUrl, "中铁工服", "宋体", 2, 24, color, 0.5f, 0, fileExtName, 5, x, y);
            // location 位置： 1、左上角，2、右上角，3、左下角，4、右下角，5、中间

//            BufferedImage targerImage = doMarkImage(ImageUtils.toImage(srcUrl), ImageUtils.toImage(FileUtils.downLoad(waterUrl)), 5, -45, x, y);
//            ImageIO.write(targerImage, fileExtName, new File(targerUrl));
            byte[] srcByte = FileUtils.inputStream2byte(input);
            String fileExtName = FileTypeDictUtils.getImageExtName(srcByte);
            byte[] bytes = markText(srcByte, "cqmall.com", "宋体", 1, 28, color, 0.2f, fileExtName, 8, 50, 50);
            ImageIO.write(ImageUtils.toImage(bytes), fileExtName, targerFile);

//            PngCompressor.compress(file,targerFile);

        } catch (Exception e) {
            e.printStackTrace();
        }



    }
}
